package com.szt.sy.service.system.menu;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.szt.sy.entity.system.Menu;
import com.szt.sy.entity.system.RoleMenu;
import com.szt.sy.mapper.system.MenuMapper;
import com.szt.sy.service.system.rolemenu.RoleMenuService;

/***
 * 菜单服务
 * 
 * @author wwy
 *
 */
@CacheConfig(cacheNames = "cache.menu")
@Service("menuService")
@Transactional(rollbackFor = RuntimeException.class)
public class MenuService extends ServiceImpl<MenuMapper, Menu> {
	
	@Autowired
	private MenuMapper menuMapper;
	
	@Autowired
	private RoleMenuService roleMenuService;
	
	/**
	 * 通过ID获取其子一级菜单
	 *
	 * @param parentId
	 * @return @
	 */
	@Cacheable
	public List<Menu> listSubMenuByParentId(Long parentId) {
		return menuMapper.selectList(new EntityWrapper<Menu>().eq("parentId", parentId).orderBy("menuSort", true));
	}
	
	/**
	 * 通过菜单ID获取数据
	 *
	 * @param pd
	 * @return @
	 */
	@Cacheable
	public Menu getMenuById(Long id) {
		return menuMapper.selectById(id);
	}
	
	/**
	 * 新增菜单
	 *
	 * @param menu
	 * @
	 */
	@CacheEvict(allEntries = true)
	public void saveMenu(Menu entity) {
		entity.setAddDate(new Date());
		entity.setVersion(1L);
		menuMapper.insert(entity);
	}
	
	/**
	 * 删除菜单
	 *
	 * @param MENU_ID
	 * @
	 */
	@CacheEvict(allEntries = true)
	public void deleteMenuById(Long id) {
		menuMapper.deleteById(id);
	}
	
	/**
	 * 编辑
	 *
	 * @param menu
	 * @return @
	 */
	@CacheEvict(allEntries = true)
	public void edit(Menu menu) {
		menuMapper.updateById(menu);
	}
	
	/**
	 * 保存菜单图标
	 *
	 * @param pd
	 * @return @
	 */
	@CacheEvict(allEntries = true)
	public void editicon(String id, String menuIcon) {
		Menu menu = new Menu();
		menu.setMenuIcon(menuIcon);
		menuMapper.update(menu, new EntityWrapper<Menu>().eq("id", id));
	}
	
	/**
	 * 获取所有菜单并填充每个菜单的子菜单列表(菜单管理)(递归处理)
	 *
	 * @param MENU_ID
	 * @return @
	 */
	@Cacheable
	public List<Menu> listAllMenu(Long id) {
		List<Menu> menuList = this.listSubMenuByParentId(id);
		for (Menu menu : menuList) {
			menu.setInMenuUrl("/admin/menu/toEdit.do?id=" + menu.getId());
			menu.setSubMenu(this.listAllMenu(menu.getId()));
			menu.setTarget("treeFrame");
		}
		return menuList;
	}
	
	@Cacheable
	public List<Menu> getAllMenuByRoleId(Long pid) {
		List<Menu> menuList = this.listSubMenuByParentId(pid);
		for (Menu menu : menuList) {
			menu.setSubMenu(this.getAllMenuByRoleId(menu.getId()));
		}
		return menuList;
	}
	
	@Cacheable
	public List<Menu> getAllMenuAuthorityByRole(String roleId) {
		List<RoleMenu> roleMenuList = roleMenuService.selectByRoleId(roleId);
		List<Menu> menuList = getAllMenuByRoleId(Menu.ROOT_ID);
		setMenuAuth(menuList, roleMenuList, false);
		return menuList;
	}
	
	@Cacheable
	public List<Menu> getAllMenuAuthorityByRole(String roleId, boolean isAdmin) {
		List<RoleMenu> roleMenuList = roleMenuService.selectByRoleId(roleId);
		List<Menu> menuList = getAllMenuByRoleId(Menu.ROOT_ID);
		setMenuAuth(menuList, roleMenuList, isAdmin);
		return menuList;
	}
	
	private void setMenuAuth(List<Menu> menuList, List<RoleMenu> roleMenuList, boolean isAdmin) {
		for (Menu menu : menuList) {
			boolean own = roleMenuList.parallelStream().filter((roleMenu) -> {
				if (roleMenu.getMenuId().equals(menu.getId())) {
					return true;
				}
				return false;
			}).count() > 0;
			if (isAdmin) {
				own = isAdmin;
			}
			menu.setOwnMenuRights(own);
			if (menu.getSubMenu() != null && menu.getSubMenu().size() > 0) {
				setMenuAuth(menu.getSubMenu(), roleMenuList, isAdmin);
			}
		}
	}
	
}
